package semaphore;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 信号量失败处理示例
 * 演示信号量在超时情况下的处理方式
 */
public class SemaphoreFailureExample {
    
    private static final Semaphore semaphore = new Semaphore(2); // 只有2个许可
    private static final AtomicInteger successCount = new AtomicInteger(0);
    private static final AtomicInteger failureCount = new AtomicInteger(0);
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== 信号量超时失败处理示例 ===");
        System.out.println("信号量许可数: 2");
        System.out.println("任务执行时间: 5秒");
        System.out.println("获取许可超时时间: 3秒");
        System.out.println("创建6个任务，观察超时失败情况\n");
        
        // 创建6个任务
        Thread[] threads = new Thread[6];
        for (int i = 0; i < 6; i++) {
            final int taskId = i + 1;
            threads[i] = new Thread(new Task(taskId));
            threads[i].start();
            
            // 稍微错开启动时间
            Thread.sleep(200);
        }
        
        // 等待所有线程完成
        for (Thread thread : threads) {
            thread.join();
        }
        
        System.out.println("\n=== 执行结果统计 ===");
        System.out.println("成功执行任务数: " + successCount.get());
        System.out.println("失败任务数: " + failureCount.get());
        System.out.println("总任务数: " + (successCount.get() + failureCount.get()));
    }
    
    static class Task implements Runnable {
        private final int taskId;
        
        public Task(int taskId) {
            this.taskId = taskId;
        }
        
        @Override
        public void run() {
            try {
                System.out.println("任务-" + taskId + " 尝试获取许可...");
                
                // 尝试在3秒内获取许可
                if (semaphore.tryAcquire(3, TimeUnit.SECONDS)) {
                    try {
                        System.out.println("✅ 任务-" + taskId + " 获得许可，开始执行 (可用许可: " + 
                                         semaphore.availablePermits() + ")");
                        
                        // 模拟长时间任务（5秒）
                        Thread.sleep(5000);
                        
                        System.out.println("✅ 任务-" + taskId + " 执行完成");
                        successCount.incrementAndGet();
                        
                    } finally {
                        semaphore.release();
                        System.out.println("🔓 任务-" + taskId + " 释放许可 (可用许可: " + 
                                         semaphore.availablePermits() + ")");
                    }
                } else {
                    // 获取许可超时
                    System.out.println("❌ 任务-" + taskId + " 获取许可超时，任务失败！");
                    failureCount.incrementAndGet();
                    
                    // 这里可以实现失败处理逻辑
                    handleTaskFailure(taskId);
                }
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("⚠️ 任务-" + taskId + " 被中断");
                failureCount.incrementAndGet();
            }
        }
        
        private void handleTaskFailure(int taskId) {
            System.out.println("🔄 任务-" + taskId + " 失败处理：记录日志、发送通知或重试");
            // 实际应用中可以：
            // 1. 记录失败日志
            // 2. 发送告警通知
            // 3. 将任务放入重试队列
            // 4. 返回错误响应给客户端
        }
    }
}
